package manager

import (
	"encoding/json"
	"errors"
	"time"

	"gitcode.com/G-YT/baoyou/server/global"
	mgrModel "gitcode.com/G-YT/baoyou/server/model/manager"
	mgrReq "gitcode.com/G-YT/baoyou/server/model/manager/request"
	mgrResp "gitcode.com/G-YT/baoyou/server/model/manager/response"
	"gitcode.com/G-YT/baoyou/server/utils"
	"gorm.io/gorm"
)

type MessageNoticeService struct{}

type msgItem struct {
	Content string `json:"content"`
	Ts      string `json:"ts"`
}

func (s *MessageNoticeService) CreateNotice(hmID uint, req mgrReq.CreateNoticeReq) error {
	now := time.Now().In(utils.Shanghai())
	start := utils.DateStartCST(now)
	end := utils.DateEndCST(now)

	var existing mgrModel.MessageNotice
	err := global.GVA_DB.Where("hm_id = ? AND user_id = ? AND day BETWEEN ? AND ?", hmID, req.UserID, start, end).First(&existing).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		items := []msgItem{{Content: req.Message, Ts: now.Format(time.RFC3339)}}
		b, _ := json.Marshal(items)
		rec := mgrModel.MessageNotice{
			HmID:     hmID,
			UserID:   req.UserID,
			Day:      start,
			Messages: b,
			Status:   0,
		}
		return global.GVA_DB.Create(&rec).Error
	} else {
		var items []msgItem
		if len(existing.Messages) > 0 {
			_ = json.Unmarshal(existing.Messages, &items)
		}
		items = append(items, msgItem{Content: req.Message, Ts: now.Format(time.RFC3339)})
		b, _ := json.Marshal(items)
		return global.GVA_DB.Model(&mgrModel.MessageNotice{}).
			Where("id = ?", existing.ID).
			Updates(map[string]interface{}{"messages": b, "status": uint(0)}).Error
	}
}

func (s *MessageNoticeService) GetTodayUnreadStatus(userID uint) (status uint, err error) {
	now := time.Now().In(utils.Shanghai())
	start := utils.DateStartCST(now)
	end := utils.DateEndCST(now)
	var ms mgrModel.MessageNotice
	firstErr := global.GVA_DB.First(&ms, "user_id = ? AND day BETWEEN ? AND ?", userID, start, end).Error
	if !errors.Is(firstErr, gorm.ErrRecordNotFound) {
		return ms.Status, firstErr
	} else {
		return 1, nil
	}
}

func (s *MessageNoticeService) GetMessageList(userID uint) (mgrResp.MessageListResp, error) {
	now := time.Now().In(utils.Shanghai())
	todayStart := utils.DateStartCST(now)
	sevenDaysAgo := todayStart.AddDate(0, 0, -6)

	var rows []mgrModel.MessageNotice
	if err := global.GVA_DB.Where("user_id = ? AND day BETWEEN ? AND ?", userID, sevenDaysAgo, utils.DateEndCST(now)).
		Preload("HealthManager").
		Order("day ASC").Find(&rows).Error; err != nil {
		return mgrResp.MessageListResp{List: map[string][]mgrResp.MessageItem{}}, err
	}

	out := make(map[string][]mgrResp.MessageItem)
	for _, r := range rows {
		key := r.Day.In(utils.Shanghai()).Format("01-02")
		var items []msgItem
		if len(r.Messages) > 0 {
			_ = json.Unmarshal(r.Messages, &items)
		}
		avatar := r.HealthManager.Avatar
		for _, it := range items {
			out[key] = append(out[key], mgrResp.MessageItem{Content: it.Content, Ts: it.Ts, Avatar: avatar})
		}
	}

	// 将当天的消息状态改为已读
	_ = global.GVA_DB.Model(&mgrModel.MessageNotice{}).
		Where("user_id = ? AND day BETWEEN ? AND ?", userID, todayStart, utils.DateEndCST(now)).
		Update("status", uint(1)).Error

	return mgrResp.MessageListResp{List: out}, nil
}
